//
//  NSObject+Description.m
//  MApiSample
//
//  Created by IOS_HMX on 17/5/16.
//  Copyright © 2017年 Mitake. All rights reserved.
//

#import "NSObject+Description.h"
static NSString *kF10RequestType = nil;

NS_INLINE NSDictionary * DescriptionMap(NSString *class){
    static NSDictionary *dic;
    static dispatch_once_t once;
    dispatch_once(&once, ^{
        NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Description" ofType:@"json"];
        NSData *data = [NSData dataWithContentsOfFile:filePath];
        dic = [NSJSONSerialization  JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
    });
    return dic[class];
}
@implementation NSObject(Description)

-(NSString *)mapi_description:(Class)class
{
    NSString *str = self.description;
    if ([self isKindOfClass:[NSString class]]){
        str = [str stringByReplacingOccurrencesOfString:@"\r" withString:@""];
        str = [str stringByReplacingOccurrencesOfString:@"\n" withString:@""];
    }
    return str;
}

@end
@implementation NSArray(Description)

-(NSArray *)mapi_description:(Class)class
{
    NSMutableArray *array = [NSMutableArray array];
    [self enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if ([obj isKindOfClass:[NSDictionary  class]] || [obj isKindOfClass:[NSArray class]]) {
            [array addObject:[obj mapi_description:class]];
        }else {
            [array addObject:[obj mapi_description:[obj class]]];
        }
    }];
    return array;
}

@end

@implementation NSDictionary(Description)

-(NSDictionary *)mapi_description:(Class)class
{
    NSString *classString = NSStringFromClass(class);
    //临时这么改
    if ([classString isEqualToString:@"MF10Response"]) {
        classString = [NSString stringWithFormat:@"%@_%@",classString,kF10RequestType];
    }
    NSString *mapName = [NSString stringWithFormat:@"%@_map",classString];
    NSMutableDictionary *map = [DescriptionMap(mapName) mutableCopy];
    
    NSMutableDictionary *dic = [NSMutableDictionary dictionary];
    [self enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
        
        if ([obj isKindOfClass:[NSDictionary  class]] || [obj isKindOfClass:[NSArray class]]) {
            [dic setObject:[obj mapi_description:class] forKey:map[key]?[NSString stringWithFormat:@"%@(%@)",map[key],key]:key];
        }else {
            if (map) {
                [dic setObject:[obj mapi_description:[obj class]] forKey:map[key]?[NSString stringWithFormat:@"%@(%@)",map[key],key]:key];
            }else {
                [dic setObject:[obj mapi_description:[obj class]] forKey:key];
            }
        }
    }];
    return dic;
}

@end

@implementation MApiModel(Description)
-(NSDictionary *)descriptionMap:(Class )class
{
    NSString *classString = NSStringFromClass(class);
    //临时这么改
    if ([classString isEqualToString:@"MF10Response"]) {
        kF10RequestType = [[self valueForKey:@"request"] valueForKey:@"requestType"];
    }
    NSMutableDictionary *map = [DescriptionMap(classString) mutableCopy];
    if (map) {
        [map addEntriesFromDictionary:[self descriptionMap:class.superclass]];
        return map;
    }else {
        return nil;
    }
    
}
-(NSDictionary *)mapi_description:(Class)class
{
    NSDictionary *map = [self descriptionMap:class];
    if (map) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
        NSMutableDictionary *dict = [NSMutableDictionary dictionary];
        for (__unsafe_unretained NSString *key in [self performSelector:@selector(descriptionProperties) withObject:nil])
        {
            id value = [self valueForKey:key];
            NSString *mapKey = map[key];
            if (mapKey==nil) {
                continue;
            }
            if (value) {
                if ([value isKindOfClass:[NSDictionary class]] || [value isKindOfClass:[NSArray class]]) {
                    dict[[NSString stringWithFormat:@"%@(%@)",map[key],key]] = [value mapi_description:class];
                }else {
                    dict[[NSString stringWithFormat:@"%@(%@)",map[key],key]] = [value mapi_description:[value class]];
                }
            }
            else {
                dict[[NSString stringWithFormat:@"%@(%@)",map[key],key]] = [NSNull null];
            }
        }
        return dict;
    }else {
        NSMutableDictionary *dict = [NSMutableDictionary dictionary];
        for (__unsafe_unretained NSString *key in [self performSelector:@selector(descriptionProperties) withObject:nil])
        {
            id value = [self valueForKey:key];
            if (value) dict[key] = value;
            else dict[key] = [NSNull null];
        }
        return dict;
    }
#pragma clang diagnostic pop
}

@end